//////////////////////////////////////////////////////
// 程序名称：用中点画圆法画椭圆
// 功 能：暂时只能画长轴和短轴在坐标轴方向的椭圆
// 编译环境：Visual Studio 2017，EasyX_20190219(beta)
// 作 者：xyqlx<mxxyqlx@qq.com>
// 最后修改：2019-3-7
#include <conio.h>
#include <graphics.h>
#include <cmath>

void MidpointStdEllipse(int x0,int y0,int a,int b,COLORREF color);

int main()
{
	// 创建绘图窗口，大小为 640x480 像素
	initgraph(640, 480);
	//填充背景为白色
	setbkcolor(WHITE);
	cleardevice();
	//开始绘制
	setlinecolor(RED);
	
	//画一些椭圆
	int al[] = { 100, 120, 150, 180, 200 };
	int bl[] = {200, 180, 150, 120, 100};
	for (int i = 0; i < 5;++i)
		MidpointStdEllipse(320, 240, al[i], bl[i], RED);

	//结束绘制
	_getch();              // 按任意键继续
	closegraph();          // 关闭绘图窗口
	return 0;
}

//x0,y0:椭圆中心参数 a:横轴长 b:纵轴长
void MidpointStdEllipse(int x0,int y0,int a,int b,COLORREF color){
	//计算必要参数
	int x, y, d;
	x = 0;
	y = b;
	int px = a * a / sqrt(a * a + b * b);
	int py = b * b / sqrt(a * a + b * b);
	d = b*b+(-b+0.25)*a*a;
	putpixel(x + x0, y + y0, color);
	putpixel(x + x0, -y + y0, color);
	putpixel(-x + x0, y + y0, color);
	putpixel(-x + x0, -y + y0, color);
	while (x <= px)
	{
		if (d < 0)
		{
			d += (2*x+3)*b*b;
			x++;
		}
		else
		{
			d += (2*x+3)*b*b+(-2*y+2)*a*a;
			x++;
			y--;
		}
		putpixel(x + x0, y + y0, color);
		putpixel(x + x0, -y + y0, color);
		putpixel(-x + x0, y + y0, color);
		putpixel(-x + x0, -y + y0, color);
	}
	d = 1.0f * b * b * (x + 0.5) * (x + 0.5) + a * a * (y - 1) * (y - 1) - a * a * b * b;
	while (y > 0)
	{
		if (d < 0)
		{
			d += (-2*y+3)*a*a+(2*x+2)*b*b;
			x++;
			y--;
		}
		else
		{
			d += (-2*y+3)*a*a;
			y--;
		}
		putpixel(x + x0, y + y0, color);
		putpixel(x + x0, -y + y0, color);
		putpixel(-x + x0, y + y0, color);
		putpixel(-x + x0, -y + y0, color);
	}
}